Status

Development notes, for internal use

Structure

  • BigDbServer liaises between multiple BigDb instances & simplifies the setup of BigDb instances
  • BigDb loads stored queries from disk (using LilSql), executes queries, inserts, deletes, and updates, runs migrations, and maps database rows to bigorm objects
  • BigOrm: Each BigOrm instance manages a single database row, may have getters and setters (defined in the subclass), has a simple interface for relational queries, and can be saved (update or insert), refreshed from the db, and can be deleted.

Three access layers are:

  • Orm object checks if it can be accessed
  • BigDb (covering an entire library) checks if returned ORM objects (or non-orm rows) can be accessed
  • BigDbServer also checks if returned ORM objects (or non-orm rows) can be accessed

Let's describe an example that would need all three of these systems, using Article library as an example, which contains articles, authors, and tags. This Article library would be setup on a website using a BigDbServer.

  1. ArticleOrm allows access if public OR if user-definable callback is_author($articleOrm) returns true
  2. ArticlesBigDb allows access to items if they are public, or if user-definable callback can_access($ormObject) returns true
  3. MyBigDbServer defines is_author, and can_access. Additionally, it blocks all access if the website is in test mode and the active user is NOT an admin. Additionally, it allows all access if the active user is an admin.
    • Note: is_author and can_access are probably best to be defined in an interface within the Articles library, so the custom server should implement that interface.

May 24, 2023

BigDb & BigOrm are probably done, except for the access layer. They're both very well documented & pretty thoroughly tested (BigOrm is probably better tested). Need to build BigDbServer, the access layer, document both, then any supplementary features that I want/need.

Also, need to consider extensibility of libraries. BigDb is highly extensible, but is a BigDb library highly extensible? Say, if a web-developer wants to make changes to a database-library they're using, can they overwrite the library's bigdb class, it's ORMs, add queries to it? Idunno. That's probably a BigDbServer question. Idon'tknow.

May 19, 2023

I pretty much finished BigOrm stuff except for the access layer. I started on BigDb, finishing two test methods. I still haven't touched the access stuff & i'm not entirely sure how to integrate it. The code is mostly organized into traits. I need to document the methods actually intended for use by end-users, as well as how to setup a bigdb instance.

So next is:

  • DONE nicely document the BigDb features for end-users
  • DONE nicely document the BigDb features for library developers
  • start developing the access/permissions layer on BigDb & BigOrm
  • Build relational lookup for Orms
  • Start work on BigDbServer

May 18, 2023

Lots of work on BigOrm (& tests).

TODO:

  • relational lookup on orm - this should go through bigdb, so orm objects can be easily loaded. Manual instantiation is always available too.
  • DONE delete hooks on orm
  • access on orm
  • DONE $orm->set_from_form(array $data)
  • NOT NOW (maybe) add onFailSave() and onFailDelete()

I got saving, deleting, and most hooks setup on the Orm object. Haven't really started on BigDb & haven't even made a placeholder class for BigDb server. haven't started on access stuff at all either. See notes below for more information.

May 16, 2023 (end of day, progress report)

I sussed out the high-level architecture & started setting up tests to figure out some of the lower level things. I have test cases in BigOrm test class. I have an input class Article which is implementing some BigOrm features, though in a very rudimentary, straightforward way (though maybe a bit much boilerplate? idk). Basically, I tested setting the object from a db row & getting a db storeable row from the object, but there's no magic happening - just overridden methods in the Article input class.

Next is to setup the saving & querying of Orm objects. This will probably start to require BigDb being passed to the Orm objects, since I want convenience methods.

Going forward, I think I'll need a base BigOrm class with core features (maybe make it abstract with some methods that have to be implemented by the subclass). Then I can build differently-featured subclasses that are generally intended for extension. The first version would be hecka straightforward & the most performant (basically what Article is doing right now). A second version might provide more magic to make Developer QoL better, at the cost of performance. Any actual item could subclass BigOrm, BigDb\FastOrm, BigDb\MagicOrm, or whatever ... So I'll need a BigOrm interface probably, unless I just require subclassing.

I haven't started working with anything access/permission related. I think BigOrm will have methods for this, but on its own it won't check access. BigDb will instantiate bigorm instances when loading from db, then perform access checks on them by calling $ormInstance->can_access(...) or something. I don't know how that will work exactly.

And I haven't done any lifecycle stuff. In my notes below, I discussed the high-level access setup, but never got into the lifecycle stuff. I think lifecycle is important, and I will need to figure this out.

And there's other things to include/figure out like sanitizing form data & setting the object from form data. As well as access related to saving, maybe?

Oh, and I haven't written any docs yet.

May 16, 2023 (initial design phase)

Created repo & copied code in from LilDb. Need to setup bigdb on packagist + git integration. After that's done, I'd like to remove BigDb from LilDb entirely. And I think I want to entirely remove the dependence on LilDb. (but maybe I keep it bc LilSql is phenomenal)

So, what should BigDb do?

  • query for ORM objects
  • raw query for array rows
  • raw insert, update delete
  • simplified insert, update, delete
  • Load ORM objects
  • Run stored queries & return ORM objects or array rows

BigDb should handle global operations, and BigOrm should handle item-specific operations (even if it uses BigDb on the backend)

BigDb should be overrideable so convenience methods can be added for a library.

BigDb has two purposes. One is to make libraries that are really easy to work with. The other is for website development. I'm not sure how a website would smoothly work with multiple different libraries that all have their own BigDb implementation.

What I want from a website perspective is a single object that can interact with all my bigdb libraries.

What I want from a library perspective is a single object to manage & query all its built-in ORM objects.

The library needs convenience methods for certain common queries. The website needs some kind of convenient access too.

I don't want the website to have to manually manage a bunch of different bigdb instances.

So maybe I make a BigDbServer, which can hold multiple BigDb instances, then each BigDb is responsible for its own BigOrms & queries.

So if I use a BigDbServer, how do the BigDb instances get initialized?

I suppose each library should have its own, even if it isn't subclassing BigDb.

The easiest thing (from a web-dev standpoint) would be $bigDbServer->addBigDb(__DIR__.'/vendor/taeluf/some-library/'), or in the case of a subclass: $bigDbServer->addBigDb(BigDbSubclass::class)

What do you do if different bigdb instances require a different PDO instance? $bdbServ->addBigDb($dir, ?\PDO $pdoInstance = null)

Then to step it up a notch, I could have a config for BigDbServer, so the actual code setup is just $bdbServ = BigDbServer::from_config('path/to/file.json').

Each BigDb instance should have a map of orm classes to database tables. They should be able to operate dynamically, without an explicit map, too, though.

But then, how should website code interact with bigdb instances?

Let's say there are two libraries built with BigDb, called 'DiffsDb' and 'Articles'. Loading articles could be one of:

  • $bdbserv->select('article', ['id'=>3])
  • $bdbserv->articles->select('article', ['id'=>3]) (keep in mind Articles is a library that has multiple DB tables, like author and tags)

I prefer the second version, because it keeps things clean & it maintains a single access point (bigdbserv). Skipping the ->articles-> and just doing $bdbserv->select(...) just ... idk. Feels like it will be confusing, hard to code, and have a lot of overhead.

If we forget option #1 & go with $bdbserv->articles->select(...), then the only real question is, how does 'articles' get set? It must be a dynamic property, unless website owners are required to subclass the server (I don't want to require this)

So, I believe I will impose a certain structure on libraries that use the option of settnig up via directory. Libraries that subclass bigdb, however, can do whatever they want. That puts the onus (sp? like 'responsibility', but pronounced "own-us") on the BigDb class. The default bigdb class would actuall define the directory structure, and subclasses can load their files as they wish.

So, let's break it down:

  • BigDbServer liaises between multiple BigDb instances & simplifies the setup of BigDb instances
  • BigDb loads stored queries from disk (using LilSql), executes queries, inserts, deletes, and updates, runs migrations, and maps database rows to bigorm objects
  • BigOrm: Each BigOrm instance manages a single database row, may have getters and setters (defined in the subclass), has a simple interface for relational queries, and can be saved (update or insert), refreshed from the db, and can be deleted.

But, what about access? The website owner should always have final say about access (i.e. the person using a library, not the library itself). However, it could be very helpful for a library to have some built-in access features. Perhaps a library will always allow access to public articles, but will call a special extensible function for non-public articles (the library shouldn't care about user-management, so should use simple extensibility to let the user of the library handle access). The user of the library should be able to further limit access to public articles if they so choose, though.

This may mean that I'm going for a multi-layered (and probably not very performant) access system. The three access layers are:

  • Orm object checks if it can be accessed
  • BigDb (covering an entire library) checks if returned ORM objects (or non-orm rows) can be accessed
  • BigDbServer also checks if returned ORM objects (or non-orm rows) can be accessed

Let's describe an example that would need all three of these systems, using Article library as an example, which contains articles, authors, and tags. This Article library would be setup on a website using a BigDbServer.

  1. ArticleOrm allows access if public OR if user-definable callback is_author($articleOrm) returns true
  2. ArticlesBigDb allows access to items if they are public, or if user-definable callback can_access($ormObject) returns true
  3. MyBigDbServer defines is_author, and can_access. Additionally, it blocks all access if the website is in test mode and the active user is NOT an admin. Additionally, it allows all access if the active user is an admin.
    • Note: is_author and can_access are probably best to be defined in an interface within the Articles library, so the custom server should implement that interface.

Questions:

  1. How do ArticlesBigDb and ArticleOrm get their callbacks?
  2. What is the logic flow for running a query, such that it will run through all these access layers?

Q#1: First, limits: I intend to use PDO::FETCH_OBJECT, which means I can't use __construct(...) arguments. That means a setter is required on an OrmObject to pass in an access layer, UNLESS the OrmObject uses BigDb (also via a setter) to get to its access layer. I honestly don't really want the orm subclasses to have to define their own setters. Since OrmObjects are initialized at runtime, outside of a setup loop, I think ... I think the access layer should be set at the server or bigdb level, then the ormobject should check with bigdb.

SO: BigOrm will use $this->_db->access->is_author(). Or maybe $this->getAccess()->is_author(), where getAccess() just return $this->_db->access

I think I need to figure some of these things out by programming it, but what about question 2?

First, I want to say ... I need to test BigOrm first, make sure it works how I want, THEN start on BigDb. BUT, BigOrm relies on BigDb so... Anyway, I want to code from the bottom up. The lowest layer (bigorm) should be able to be used independently (even if it has a bigdb instance for some internal operations).